#include "ManejadorConteo.h"

using namespace Manejadores;

ManejadorConteo::ManejadorConteo() {
	Configuracion* config = Configuracion::getInstancia();
	string pathDeDatos = config->getNombreArchivoConteo();
	this->conteos = new ArchivoDeEstructurasVariables(pathDeDatos);
	this->indicePorIDdeConteo = new HashExtensible("IndicePorUnicidadConteo");
	this->indicePorFechaYDistrito = new ArbolBMas("PorFechaYDistrito");
	this->indicePorEleccion = new ArbolBMas("PorEleccion");
	this->indicePorLista = new ArbolBMas("PorLista");
}

void ManejadorConteo::alta(string fecha,string cargo,string distrito,string nombreLista,int voto) {

	Conteo* conteo = new Conteo();
	conteo->setEleccion(atoi(fecha.c_str()), cargo);
	conteo->setLista(nombreLista);
	conteo->setDistrito(distrito);
	conteo->setCantidadDeVotos(voto);

	unsigned int posicionDelRegistro = conteos->insertar(conteo);

	string clavePorUnicidad = fecha + cargo + nombreLista + distrito;
	indicePorIDdeConteo->insertar(clavePorUnicidad, posicionDelRegistro);

	string claveIndiceFechaYDistrito = fecha + distrito;
	indicePorFechaYDistrito->insertar(claveIndiceFechaYDistrito, posicionDelRegistro);

	string claveIndiceEleccion = fecha  + cargo;
	indicePorEleccion->insertar(claveIndiceEleccion, posicionDelRegistro);

	string claveIndiceLista = claveIndiceEleccion + nombreLista;
	indicePorLista->insertar(claveIndiceLista, posicionDelRegistro);


}

void ManejadorConteo::registrarVoto(string fecha,string cargo,string distrito,string nombreLista){

	string clavePorUnicidad = fecha + cargo + nombreLista + distrito;
	IRegistroIndice* registro = indicePorIDdeConteo->buscar(clavePorUnicidad);
	if (registro->getOffsets()->size() == 0) {
		this->alta(fecha, cargo,distrito,nombreLista,1);
	}else{
		Conteo* conteo = new Conteo();
		this->conteos->leer(conteo,registro->getOffsets()->at(0));
		conteo->sumarUnVoto();
		this->conteos->modificar(conteo,registro->getOffsets()->at(0));
		delete conteo;
	}

}
/*
 * Reportes del archivo conteo.
 */

void ManejadorConteo::reportePorDistrito(string distrito, int fecha){

	Configuracion* config = Configuracion::getInstancia();
	string path = config->getPathReportes() + "reportePorDistrito" + ".txt";
	fstream reportePorDistrito;

	reportePorDistrito.open(path.c_str(), ios::out | ios::app);
	if (reportePorDistrito.bad()) {
		reportePorDistrito.open(path.c_str(), ios::out);
	}

	string claveFecha = Utils::convertirEnteroAString(fecha);

	string claveDeRecuperacion = claveFecha+ distrito;
	IRegistroIndice* conteos = this->indicePorIDdeConteo->buscar(claveDeRecuperacion);
	string eleccionAnterior = "";
	string eleccionActual;
	string listaActual;
	string listaAnterior = "";
	reportePorDistrito << "Informe de elecciones realizadas en el distrito: "<< distrito<< " el dia "<< claveFecha << endl;

	for (unsigned int i; i < conteos->getOffsets()->size(); i++) {

		Conteo* conteo = new Conteo();
		this->conteos->leer(conteo, conteos->getOffsets()->at(i));

		string fechaEleccion = Utils::convertirEnteroAString(conteo->getEleccion()->getFecha());
		eleccionActual = fechaEleccion + conteo->getEleccion()->getCargo()->getNombre();

		if (eleccionAnterior != eleccionActual) {
			eleccionAnterior = eleccionActual;
			listaAnterior = "";
			reportePorDistrito << "Elecciones para " << conteo->getEleccion()->getCargo()->getNombre() << " el dia " << conteo->getEleccion()->getFecha() << endl;
			reportePorDistrito << " " << endl;
		}

		listaActual = conteo->getLista()->getNombre();

		if (listaActual != listaAnterior) {
			listaAnterior = listaActual;
			reportePorDistrito << "Lista : " << listaActual << conteo->getCantidadDeVotos() << endl;
			reportePorDistrito << " " << endl;
		}

	}

	reportePorDistrito.close();

}

ManejadorConteo::~ManejadorConteo() {
	delete this->conteos;
	delete this->indicePorLista;
	delete this->indicePorIDdeConteo;
	delete this->indicePorFechaYDistrito;
	delete this->indicePorEleccion;
	delete this->indicePorLista;
}
